/* $RCSFile: ADNDynProduct.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/CRMWrapper3/DynEntities/ADNDynProduct.cs $
 * $log$
 * Revision 19 2010/10/02 14:01:49  christian.surieux
 *   Corrected a bug in allmost everyADNDyn file for PrimaryFieldVualue
 * Revision 6 2010/08/06 19:56:33  christian.surieux
 *   Added Log to All cs files
 */

using System;
using System.Diagnostics;
using System.Collections;
using System.ComponentModel;
using System.Collections.Generic;
using System.Text;
using System.Globalization;

using CrmSdk;

namespace AddonNice.CRMWrapper
{
	public class ADNDynProduct : DynEntity
	{
        protected class Ftor: DFactor
        {
            public Ftor() : base(CrmStr.product)
            {}

            public override Type DynType
            { get { return typeof(ADNDynProduct); } }

            public override string DynTypename
            {   get{ return CrmStr.product;}}

            public override DynEntity Build()
            {   return new ADNDynProduct();}

            public override DynEntity Build(CRMWrapperBase w, InternalDynamicEntity dEntity, PropertyDescriptorCollection wproperties)
            {   return new ADNDynProduct(w, dEntity, wproperties, null);}

            public override DynEntity Build(CRMWrapperBase w, string PrimaryFieldValue)
            {   return new ADNDynProduct(w,PrimaryFieldValue);}

            public override DynEntity Build(CRMWrapperBase w,Guid PrimaryKeyValue)
            {   return new ADNDynProduct(w,PrimaryKeyValue);}
        }

        static ADNDynProduct(){new Ftor();} 

        public override bool HasOwnerProperty
        {
            get{   return false;}
        }

        public override bool HasBusinessUnitProperty
        {
            get{   return false;}
        }

        /// <summary>
		/// Reserved for template methods: do not use directly
		/// </summary>
        public ADNDynProduct(): base()
		{}

        public ADNDynProduct(CRMWrapperBase w, string PrimaryFiedlValue)
			: base(w,CrmStr.product)
		{
			name = PrimaryFiedlValue;
		}
        public ADNDynProduct(ResetWrapperHandler fn,string PrimaryFiedlValue)
			: base(fn,CrmStr.product)
		{
			name = PrimaryFiedlValue;
		}

		public ADNDynProduct(CRMWrapperBase w, Guid CrmId)
			: base(w,CrmStr.product, CrmId)
		{}
        
		public ADNDynProduct(ResetWrapperHandler fn,Guid CrmId)
			: base(fn,CrmStr.product, CrmId)
		{}
		public ADNDynProduct(CRMWrapperBase w, InternalDynamicEntity e)
			: base(w,CrmStr.product,e,null,null)
		{}
		public ADNDynProduct(ResetWrapperHandler fn,InternalDynamicEntity e)
			: base(fn,CrmStr.product,e,null,null)
		{}

		public ADNDynProduct(CRMWrapperBase w, InternalDynamicEntity e,PropertyDescriptorCollection prop,InternalColumnSet s)
			: base(w,CrmStr.product,e,prop,s)
		{}

		public ADNDynProduct(ResetWrapperHandler fn,InternalDynamicEntity e,PropertyDescriptorCollection prop,InternalColumnSet s)
			: base(fn,CrmStr.product,e,prop,s)
		{}

        /// <summary>
		/// Crm Key
		/// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public Guid productid
		{
			get
			{
				return KeyPropertyValue(CrmStr.productid);
			}
			set
			{
				AddKeyProperty(CrmStr.productid, value);
			}
		}

        protected override void SetCrmIdProperty(Guid crmId)
        {
           if ( !dicProperty.ContainsKey(CrmStr.productid) || KeyPropertyValue(CrmStr.productid) != crmId )
                productid   =   crmId;
        }
        
        public override string PrimaryFieldName
        {
            get
            {
               return CrmStr.name;
            }
           set
           {}
        }

        /// <summary>
        /// Value contained in the PrimaryField for the DynEntity or empty if no PrimaryField
        /// </summary>
        public override string PrimaryFieldStringValue
        {
            get
            {
                return name;
            }
            set
            {
                name =   value;
            }
        }

        public override Guid PrimaryKeyGuidValue
        {
           get
           {
                return productid;
           }
           set
           {
               productid    =   value;
           }
        }

        /// <summary>
        /// Gets the exchange rate for the currency associated with the product with respect to the base currency.
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public decimal exchangerate
        {
            get
            {
                return DecimalPropertyValue(CrmStr.exchangerate);
            }
            set
            {
                AddDecimalProperty(CrmStr.exchangerate,value);
            }
        }

        /// <summary>
        /// Specifies the default unit for the product. 
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public Guid defaultuomid 
        {
            get
            {
                if ( ContainsKey(CrmStr.defaultuomid) )
                    return LookupPropertyValue(CrmStr.defaultuomid);
                return Guid.Empty;
            }
            set
            {
                AddLookupProperty(CrmStr.defaultuomid,CrmStr.uom,value);
            }
        }

        public string defaultuomName
        {
            get
            {
                if (ContainsKey(CrmStr.defaultuomid))
                    return LookupPropertyName(CrmStr.defaultuomid);
                return string.Empty;
            }
        }

        /// <summary>
        /// Specifies the default unit group for the product. 
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public Guid defaultuomscheduleid
        {
            get
            {
                if (ContainsKey(CrmStr.defaultuomscheduleid))
                    return LookupPropertyValue(CrmStr.defaultuomscheduleid);
                return Guid.Empty;
            }
            set
            {
                AddLookupProperty(CrmStr.defaultuomscheduleid,CrmStr.uom,value);
            }
        }

        public string defaultuomscheduleName
        {
            get
            {
                if (ContainsKey(CrmStr.defaultuomscheduleid))
                    return LookupPropertyName(CrmStr.defaultuomscheduleid);
                return string.Empty;
            }
        }

        /// <summary>
        /// Gets and sets the ID of the currency associated with the product.         
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public Guid transactioncurrencyid
        {
            get
            {
                return LookupPropertyValue(CrmStr.transactioncurrencyid);
            }
            set
            {
                AddLookupProperty(CrmStr.transactioncurrencyid,CrmStr.transactioncurrency,value);
            }
        }

        public string transactioncurrencyName
        {
            get
            {
                return LookupPropertyName(CrmStr.transactioncurrencyid);
            }
        }

        /// <summary>
        /// Contains the description of the product. 
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public string description 
        {
            get
            {
                return StringPropertyValue(CrmStr.description);
            }
            set
            {
                AddStringProperty(CrmStr.description,value);
            }
        }
        
        /// <summary>
        /// Specifies whether the product is a kit. 
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public bool iskit
        {
            get 
            {
                return BooleanPropertyValue(CrmStr.iskit);
            }
            set
            {
                AddBooleanProperty(CrmStr.iskit,value);
            }
        }

        /// <summary>
        /// Specifies whether the product is a stock item. 
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public bool isstockitem 
        {
            get 
            {
                if ( ContainsKey(CrmStr.isstockitem) )
                    return BooleanPropertyValue(CrmStr.isstockitem);
                return false;
            }
            set
            {
                AddBooleanProperty(CrmStr.isstockitem,value);
            }
        }
 
        /// <summary>
        /// Flat Fees
        /// Miscellaneous Charges
        /// Sales Inventory
        /// Services
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public int producttypecode
        {
            get
            {
                return PicklistPropertyIntValue(CrmStr.producttypecode);
            }
            set
            {
                AddPicklistProperty(CrmStr.producttypecode,value);
            }
        }

        public string producttypecodeLabel
        {
            get
            {
                return PicklistPropertyLabelValue(CrmStr.producttypecode);
            }
        }

        /// <summary>
        /// Specifies the current cost for the product item. Used in price calculations. 
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public decimal currentcost
        {
            get
            {
                if ( ContainsKey(CrmStr.currentcost) )
                    return MoneyPropertyValue(CrmStr.currentcost);
                return 0m;
            }
            set
            {
                AddMoneyProperty(CrmStr.currentcost,value);
            }
        }

        /// <summary>
        /// Specifies the current cost for the product item. Used in price calculations. 
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public decimal currentcost_base
        {
            get
            {
                if ( ContainsKey(CrmStr.currentcost_base) )
                    return MoneyPropertyValue(CrmStr.currentcost_base);
                return 0m;
            }
        }
        
        
        /// <summary>
        /// Specifies the standard cost of the product. 
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public decimal standardcost
        {
            get 
            {
                if ( ContainsKey(CrmStr.standardcost) )
                    return MoneyPropertyValue(CrmStr.standardcost);
                return 0m;
            }
            set
            {
                AddMoneyProperty(CrmStr.standardcost,value);
            }
        }

        /// <summary>
        /// Gets the base currency equivalent for the standard cost of the product. 
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public decimal standardcost_base
        {
            get 
            {
                if ( ContainsKey(CrmStr.standardcost_base) )
                    return MoneyPropertyValue(CrmStr.standardcost_base);
                return 0m;
            }
        }

        /// <summary>
        /// Specifies the list price of the product. 
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public decimal price 
        {
            get 
            {
                if ( ContainsKey(CrmStr.price) )
                    return MoneyPropertyValue(CrmStr.price);
                return 0m;
            }
            set
            {
                AddMoneyProperty(CrmStr.price,value);
            }
        }

        /// <summary>
        /// Gets the base currency equivalent of the list price for the product
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public decimal price_base
        {
            get 
            {
                if ( ContainsKey(CrmStr.price_base) )
                    return MoneyPropertyValue(CrmStr.price_base);
                return 0m;
            }
        }

        /// <summary>
        /// Specifies the ID of the price list associated with the product. 
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public Guid pricelevelid
        {
            get 
            {
                if ( ContainsKey(CrmStr.pricelevelid) )
                    return LookupPropertyValue(CrmStr.pricelevelid);
                return Guid.Empty;
            }
            set
            {
                AddLookupProperty(CrmStr.pricelevelid,CrmStr.pricelevel,value);
            }
        }
 
        public string pricelevelName
        {
            get 
            {
                if ( ContainsKey(CrmStr.pricelevelid) )
                    return LookupPropertyName(CrmStr.pricelevelid);
                return string.Empty;
            }
        }

        /// <summary>
        /// Specifies the ID of the subject associated with the product. 
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public Guid subjectid
        {
            get 
            {
                return LookupPropertyValue(CrmStr.subjectid);
            }
            set
            {
                AddLookupProperty(CrmStr.subjectid,CrmStr.subject,value);
            }
        }

        public string subjectName
        {
            get 
            {
                if ( ContainsKey(CrmStr.subjectid) )
                    return LookupPropertyName(CrmStr.subjectid);
                return string.Empty;
            }
        }

        /// <summary>
        /// Specifies the user-defined product number. 
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public string productnumber 
        {
            get
            {
                return StringPropertyValue(CrmStr.productnumber);
            }
            set
            {
                AddStringProperty(CrmStr.productnumber,value);
            }
        }

        /// <summary>
        /// Specifies the name of the product's supplier. 
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public string suppliername
        {
            get
            {
                return StringPropertyValue(CrmStr.suppliername);
            }
            set
            {
                AddStringProperty(CrmStr.suppliername,value);
            }
        }
 
        /// <summary>
        /// Specifies the name of the product vendor. 
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public string vendorname
        {
            get
            {
                return StringPropertyValue(CrmStr.vendorname);
            }
            set
            {
                AddStringProperty(CrmStr.vendorname,value);
            }
        }

        /// <summary>
        /// Specifies the part number of the vendor's product. 
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public string vendorpartnumber
        {
            get
            {
                return StringPropertyValue(CrmStr.vendorpartnumber);
            }
            set
            {
                AddStringProperty(CrmStr.vendorpartnumber,value);
            }
        }
 
        /// <summary>
        /// Specifies the URL for the Web site associated with the product. 
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public string producturl
        {
            get
            {
                return StringPropertyValue(CrmStr.producturl);
            }
            set
            {
                AddStringProperty(CrmStr.producturl,value);
            }
        }
        
        /// <summary>
        /// Specifies the number of decimal places that can be used in monetary amounts for the product. 
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public int quantitydecimal
        {
            get
            {
                if ( ContainsKey(CrmStr.quantitydecimal) )
                    return NumberPropertyValue(CrmStr.quantitydecimal);
                return 0;
            }
            set
            {
                AddNumberProperty(CrmStr.quantitydecimal,value);
            }
        }

        /// <summary>
        /// Specifies the quantity of the product in stock. 
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public decimal quantityonhand
        {
            get
            {
                if ( ContainsKey(CrmStr.quantityonhand) )
                    return DecimalPropertyValue(CrmStr.quantityonhand);
                return 0m;
            }
            set
            {
                AddDecimalProperty(CrmStr.quantityonhand,value);
            }
        }

        /// <summary>
        /// Specifies the product size.
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public string size
        {
            get
            {
                return StringPropertyValue(CrmStr.size);
            }
            set
            {
                AddStringProperty(CrmStr.size,value);
            }
        }
         
        /// <summary>
        /// Specifies the stock volume of the product. 
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public decimal stockvolume
        {
            get
            {
                if ( ContainsKey(CrmStr.stockvolume) )
                    return DecimalPropertyValue(CrmStr.stockvolume);
                return 0m;
            }
            set
            {
                AddDecimalProperty(CrmStr.stockvolume,value);
            }
        }
 
        /// <summary>
        /// Specifies the stock weight of the product. 
        /// </summary>
        [CrmDynAttribute(CrmStr.product)]
        public decimal stockweight
        {
            get
            {
                if ( ContainsKey(CrmStr.stockweight) )
                    return DecimalPropertyValue(CrmStr.stockweight);
                return 0m;
            }
            set
            {
                AddDecimalProperty(CrmStr.stockweight,value);
            }
        }

        #region utilities
        
        /// <summary>
        /// To use on a kit product, add a new element to it
        /// </summary>
        public void AddProductToKit(ADNDynProduct prd,bool isAdmin)
        {
            wrapper.Util.AddProductToKit(this,prd,isAdmin);
        }

        public void RemoveProductFromKit(ADNDynProduct prd,bool isAdmin)
        {
            wrapper.Util.RemoveProductFromKit(this,prd,isAdmin);
        }
        public void ConvertProductToKit(bool isAdmin)
        {
            wrapper.Util.ConvertProductToKit(this,isAdmin);
        }
        public void ConvertKitToProduct(bool isAdmin)
        {
            wrapper.Util.ConvertKitToProduct(this,isAdmin);
        }
        public void AddSubstituteProduct(ADNDynProduct prd,bool isAdmin)
        {
            wrapper.Util.AddSubstituteProduct(this,prd,isAdmin);
        }
        public void RemoveSubstituteProduct(ADNDynProduct prd,bool isAdmin)
        {
            wrapper.Util.RemoveSubstituteProduct(this,prd,isAdmin);
        }
    
        public List<ADNDynProduct> GetSubstitutes(ResetWrapperHandler fn,bool isAdmin)
        {
            if ( CRMDynTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynProduct GetSubstitutes BEG name: {0}, isAdmin: {1}",name,isAdmin),CRMDynTraceSwitch.Sw.Info);
            List<ADNDynProduct> List                                =   new List<ADNDynProduct>();
            try
            {
                GenericDynQueryMultiple<ADNDynProduct> allEntQuery  =   new GenericDynQueryMultiple<ADNDynProduct>(wrapper,fn,CrmStr.product);
                InternalQueryExpression qe                          =   new InternalQueryExpression();
                qe.EntityName                                       =   CrmStr.product;
                InternalAllColumns RequestCols                      =   new InternalAllColumns();
                
                // link from product entity to productassociation
                InternalLinkEntity le                               =   new InternalLinkEntity();
                le.LinkFromEntityName                               =   CrmStr.product;
                le.LinkFromAttributeName                            =   CrmStr.productid;
                le.LinkToEntityName                                 =   CrmStr.productsubstitute;
                le.LinkToAttributeName                              =   CrmStr.substitutedproductid;

                // link from productassociation to product
                InternalLinkEntity le2                              =   new InternalLinkEntity();
                le2.LinkFromEntityName                              =   CrmStr.productsubstitute;
                le2.LinkFromAttributeName                           =   CrmStr.productid;
                le2.LinkToEntityName                                =   CrmStr.product;
                le2.LinkToAttributeName                             =   CrmStr.productid;

                
                InternalFilterExpression fi                         =   new InternalFilterExpression();
                // condition for productid
                InternalConditionExpression ex                      =   new InternalConditionExpression();
                ex.AttributeName                                    =   CrmStr.productid;
                ex.Operator                                         =   InternalConditionOperator.Equal;
                ex.Values                                           =   new string[]{productid.ToString()};

                //add condition to linkentity
                le2.LinkCriteria                                    =   fi;
                fi.Conditions                                       =   new InternalConditionExpression[]{ex};

                // chain linkentity2 to linkentity
                le.LinkEntities                                     =   new InternalLinkEntity[]{le2};

                //add linkentities to Query Expression 
                qe.LinkEntities                                     =   new InternalLinkEntity[]{le};
                qe.ColumnSet                                        =   RequestCols;
                
                
                InternalBusinessEntityCollection allEnt             =   (isAdmin) ? allEntQuery.adminRetrieve(qe): allEntQuery.Retrieve(qe);
                PropertyDescriptorCollection _columnDescriptors     =   null;
                EntityConfig ListMemberTConfig2                     =   new EntityConfig(wrapper,CrmStr.product);
                // Transform them in DynEntities and insert them in dynEntList
                if ( allEntQuery.RetrievedCount > 0 )
                {
                    // Transform them in DynEntities and insert them in dynEntList
                    wrapper.Util.ExecForEachDynamicEntity(allEnt,
                        delegate(InternalDynamicEntity de)
                        {
                            ADNDynProduct ob                        =   new ADNDynProduct(wrapper,de,_columnDescriptors,null);
                            ob.EntityMData                          =   ListMemberTConfig2.entityMetaData;
                            _columnDescriptors                      =   ob.PropertyDescriptorCollection;
                            List.Add(ob);
                            if ( CRMDynTraceSwitch.Sw.TraceVerbose )
                                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynProduct GetSubstitutes found entity: {0}", ob.name),CRMDynTraceSwitch.Sw.Info);
                            return true; // continue
                        });
                }
            }
            catch (Exception ex)
            {
                string msg          =   string.Format("[E]ADNDynProduct GetSubstitutes ex : {0}", ex);
                if (CRMDynTraceSwitch.Sw.TraceError)
                    Trace.WriteLine( msg,CRMDynTraceSwitch.Sw.Info);
                throw;
            }

            if ( CRMDynTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynProduct GetSubstitutes END found: {0}", List.Count),CRMDynTraceSwitch.Sw.Info);
            return List;
        }

        public List<ADNDynProduct> GetKitMembers(ResetWrapperHandler fn,bool isAdmin)
        {
            if ( CRMDynTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynProduct GetKitMembers BEG name: {0}, isAdmin: {1}",name,isAdmin),CRMDynTraceSwitch.Sw.Info);
            List<ADNDynProduct> List                                =   new List<ADNDynProduct>();
            try
            {
                GenericDynQueryMultiple<ADNDynProduct> allEntQuery  =   new GenericDynQueryMultiple<ADNDynProduct>(wrapper,fn,CrmStr.product);
                InternalQueryExpression qe                          =   new InternalQueryExpression();
                qe.EntityName                                       =   CrmStr.product;
                InternalAllColumns RequestCols                      =   new InternalAllColumns();
                
                // link from product entity to productassociation
                InternalLinkEntity le                               =   new InternalLinkEntity();
                le.LinkFromEntityName                               =   CrmStr.product;
                le.LinkFromAttributeName                            =   CrmStr.productid;
                le.LinkToEntityName                                 =   CrmStr.productassociation;
                le.LinkToAttributeName                              =   CrmStr.associatedproduct;

                // link from productassociation to product
                InternalLinkEntity le2                              =   new InternalLinkEntity();
                le2.LinkFromEntityName                              =   CrmStr.productassociation;
                le2.LinkFromAttributeName                           =   CrmStr.productid;
                le2.LinkToEntityName                                =   CrmStr.product;
                le2.LinkToAttributeName                             =   CrmStr.productid;

                
                InternalFilterExpression fi                         =   new InternalFilterExpression();
                // condition for productid
                InternalConditionExpression ex                      =   new InternalConditionExpression();
                ex.AttributeName                                    =   CrmStr.productid;
                ex.Operator                                         =   InternalConditionOperator.Equal;
                ex.Values                                           =   new string[]{productid.ToString()};

                //add condition to linkentity
                le2.LinkCriteria                                    =   fi;
                fi.Conditions                                       =   new InternalConditionExpression[]{ex};

                // chain linkentity2 to linkentity
                le.LinkEntities                                     =   new InternalLinkEntity[]{le2};

                //add linkentities to Query Expression 
                qe.LinkEntities                                     =   new InternalLinkEntity[]{le};
                qe.ColumnSet                                        =   RequestCols;
                
                
                InternalBusinessEntityCollection allEnt             =   (isAdmin) ? allEntQuery.adminRetrieve(qe):allEntQuery.Retrieve(qe);
                PropertyDescriptorCollection _columnDescriptors     =   null;
                EntityConfig ListMemberTConfig2                     =   new EntityConfig(wrapper,CrmStr.product);
                // Transform them in DynEntities and insert them in dynEntList
                if ( allEntQuery.RetrievedCount > 0 )
                {
                    // Transform them in DynEntities and insert them in dynEntList
                    wrapper.Util.ExecForEachDynamicEntity(allEnt,
                        delegate(InternalDynamicEntity de)
                        {
                            ADNDynProduct ob                        =   new ADNDynProduct(wrapper,de,_columnDescriptors,null);
                            ob.EntityMData                          =   ListMemberTConfig2.entityMetaData;
                            _columnDescriptors                      =   ob.PropertyDescriptorCollection;
                            List.Add(ob);
                            if ( CRMDynTraceSwitch.Sw.TraceVerbose )
                                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynProduct GetKitMembers found entity: {0}", ob.name),CRMDynTraceSwitch.Sw.Info);
                            return true; // continue
                        });
                }
            }
            catch (Exception ex)
            {
                string msg          =   string.Format("[E]ADNDynProduct GetKitMembers ex : {0}", ex);
                if (CRMDynTraceSwitch.Sw.TraceError)
                    Trace.WriteLine( msg,CRMDynTraceSwitch.Sw.Info);
                throw;
            }

            if ( CRMDynTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynProduct GetKitMembers END found: {0}", List.Count),CRMDynTraceSwitch.Sw.Info);
            return List;
        }

        #endregion utilities
    }
}
